/*
	This script file is part of the Sonic 3 A.I.R. script software distribution.
	Copyright (C) 2017-2024 by Eukaryot

	Published under the GNU GPLv3 open source software license, see license.txt
	or https://www.gnu.org/licenses/gpl-3.0.en.html
*/



//-------------------------------------------------------//
// Flip Bridge from AIZ                                  //
//-------------------------------------------------------//

//# address-hook(0x02a94c) end(0x02aa50)
function void fn02a94c()
{
	objA0.mapping_offset = 0x22a310
	objA0.sprite_attributes = (sprite_attribute.PALETTE.LINE2 | 0x02e9)
	objA0.box_size.x = 0x80
	objA0.box_size.y = 0x04
	objA0.render_flags = render_flag.WORLD
	objA0.sprite_priority = 0x0200
	u16[A0 + 0x30] = objA0.position.y.u16
	u32[A0 + 0x32] = (objA0.subtype2c & 0x80) ? 0x02ab72 : 0x02aaf2

	D0.u16 = (objA0.subtype2c & 0x0f) + 0x10
	u8[A0 + 0x37] = D0.u8
	u8[A0 + 0x25] = (objA0.subtype2c >> 4) & 0x07

	D1 = 1
	if (objA0.flags2a & 0x01)
	{
		D1 = -1
		--u8[A0 + 0x37]
	}
	u8[A0 + 0x36] = D1.u8

	if (allocDynamicObjectAfterA0())
	{
		objA1.update_address = 0x02aa78
		objA1.mapping_offset = 0x22a310
		objA1.sprite_attributes = (sprite_attribute.PALETTE.LINE2 | 0x02e9)
		objA1.render_flags = render_flag.WORLD
		objA1.box_size.x = 0x80
		objA1.box_size.y = 0x40
		objA1.sprite_priority = 0x0200
		objA1.position.x.u16 = objA0.position.x.u16
		objA1.position.y.u16 = objA0.position.y.u16
		objA1.render_flags |= render_flag.COMPOUND
		objA1.compound.count = 8		// Number of bridge segments
		D2.u16 = objA0.position.y.u16 + 0x20
		D3.u16 = objA0.position.x.u16 - 0x70
		D4.u16 = 8
		if (s8(objA0.subtype2c) < 0)
		{
			// Shrink vertical distance between segments a bit
			D2.u16 -= 0x10
			D4.u16 = 4
		}

		D1 = 0
		A2 = A1 + 0x18
		D6.u16 = objA1.compound.count
		while (D6.s16 > 0)
		{
			u16[(A2+=2)-2] = D3.u16
			u16[(A2+=2)-2] = D2.u16
			u16[(A2+=2)-2] = D1.u16

			D1.u16 = (D1.u16 + 0x02) & 0x0f		// Flipping delay between segments
			D3.u16 += 0x20			// Horizontal distance between segments
			D2.u16 -= D4.u16		// Vertical distance between segments

			--D6.s16
		}
		u16[A0 + 0x3c] = A1.u16
	}
	objA0.update_address = 0x02aa56
	fn02aa56()
}


//# address-hook(0x02aa56) end(0x02aa72)
function void fn02aa56()
{
	A3 = 0xffff0000 + u16[A0 + 0x3c]
	fn02aa7e()

	D1 = objA0.box_size.x
	A2 = u32[A0 + 0x32]
	D4.u16 = objA0.position.x.u16
	fn02abf2()

	CheckForUnloadObject()
}


//# address-hook(0x02aa7e) end(0x02aaf0)
function void fn02aa7e()
{
	--objA0.animation.timer
	if (s8(objA0.animation.timer) < 0)
	{
		objA0.animation.timer = u8[A0 + 0x25]
		A2 = A3 + 0x1d
		D6.u16 = u16[A3 + 0x16] - 1
		D2.u8 = u8[A0 + 0x37]
		D1.u8 = u8[A0 + 0x36]
		if (D1.s8 < 0)
		{
			while (D6.s16 >= 0)
			{
				if (u8[A2] + D1.u8 >= u8[A2])	// Check if carry flag not set addition
				{
					u8[A2] = D2.u8
				}
				else
				{
					u8[A2] += D1.u8
				}
				A2 += 6
				--D6.s16
			}
		}
		else
		{
			while (D6.s16 >= 0)
			{
				u8[A2] += D1.u8
				if (D2.u8 <= u8[A2])
				{
					u8[A2] = 0
				}
				A2 += 6
				--D6.s16
			}
		}

		if (s8[A3 + 0x04] < 0)
		{
			D0.u8 = (level.framecounter.low + 3) & 7
			if (D0.u8 == 0)
			{
				playSound(0x4c)
			}
		}
	}
}


//# address-hook(0x02abf2) end(0x02ac06)
function void fn02abf2()
{
	push(D4)
	push(D3)
	push(D2)
	push(D1)

	A1 = 0xffffb000
	D6 = 3		// object.flag.P1_ON_OBJECT
	fn02ac08()

	D1 = pop()
	D2 = pop()
	D3 = pop()
	D4 = pop()

	A1 = 0xffffb04a
	D6.u8 = 4		// object.flag.P2_ON_OBJECT
	fn02ac08()
}


//# address-hook(0x02ac08) end(0x02acda)
function void fn02ac08()
{
	u8 bit = (1 << D6.u8)
	if (objA0.flags2a & bit)
	{
		D2.u16 = D1.u16 * 2
		if ((u8[A1 + 0x2a] & char.flag.IN_AIR) == 0)
		{
			D0.u16 = objA1.position.x.u16 - objA0.position.x.u16 + D1.u16
			if (D0.s16 >= 0 && D0.u16 < D2.u16)
			{
				D0.u16 = (D0.u16 >> 5) * 6
				D0.u8 = u8[A3 + D0.s16 + 0x1d]
				if (D0.u8 >= 0x05)
				{
					D2.u16 = D4.u16
					fn01e240()
					D4 = 0
					return
				}
			}
		}

		objA1.flags2a &= ~char.flag.ON_OBJECT
		objA1.flags2a |= char.flag.IN_AIR
		objA0.flags2a &= ~bit
		D4 = 0
		return
	}

	if (objA1.velocity.y >= 0)
	{
		D0.u16 = objA1.position.x.u16 - objA0.position.x.u16 + D1.u16
		D1.u16 *= 2
		if (D0.s16 >= 0 && D0.u16 < D1.u16)
		{
			if (objA0.render_flags & render_flag.FLIP_X)
			{
				D0.u16 = D1.u16 - D0.u16 - 1
			}

			D4.u16 = D0.u16
			D0.u16 >>= 1
			D3.s16 = s8[A2 + D0.u16]
			D0.u16 = objA0.position.y.u16 - D3.u16
			D2.u16 = objA1.position.y.u16
			D1.u16 = D2.u16 + 4 + s8[A1 + 0x1e]
			D0.u16 -= D1.u16
			if (D0.s16 <= 0 && D0.s16 >= -0x10)
			{
				if (u8[A1 + 0x2e] == 0 && u8[A1 + 0x05] < 0x06)
				{
					D4.u16 = (D4.u16 >> 5) * 6
					D4.u8 = u8[A3 + D4.s16 + 0x1d]
					if (D4.u8 >= 5)
					{
						D2.u16 += D0.u16 + 3
						objA1.position.y.u16 = D2.u16
						LetSonicClimbOnObject()
					}
				}
			}
		}
	}
}


//# address-hook(0x02aa78) end(0x02aa78)
function void fn02aa78()
{
	DrawOrUnloadObject()
}
